package org.jeecg.modules.wmhb.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.constant.UserConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.common.system.vo.SelectTreeModel;
import org.jeecg.modules.wmhb.dto.req.ProductBomReqDto;
import org.jeecg.modules.wmhb.entity.WmPlan;
import org.jeecg.modules.wmhb.entity.WmPurchaseOrder;
import org.jeecg.modules.wmhb.entity.WmTask;
import org.jeecg.modules.wmhb.entity.WmTaskBom;
import org.jeecg.modules.wmhb.mapper.WmPlanMapper;
import org.jeecg.modules.wmhb.mapper.WmPurchaseOrderMapper;
import org.jeecg.modules.wmhb.mapper.WmTaskBomMapper;
import org.jeecg.modules.wmhb.mapper.WmTaskMapper;
import org.jeecg.modules.wmhb.service.IWmPlanService;
import org.jeecg.modules.wmhb.service.IWmTaskService;
import org.jeecg.modules.wmhb.dto.res.ProductBomResDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
 * @Description: 任务
 * @Author: jeecg-boot
 * @Date:   2025-09-30
 * @Version: V1.0
 */
@Service
public class WmTaskServiceImpl extends ServiceImpl<WmTaskMapper, WmTask> implements IWmTaskService {

    @Autowired
    private WmPlanMapper planMapper;
    @Autowired
    private WmTaskBomMapper taskBomMapper;
    @Autowired
    private WmPurchaseOrderMapper purchaseOrderMapper;

	@Override
    @Transactional
	public void addWmTask(WmTask wmTask) {
	   //新增时设置hasChild为0
	    wmTask.setHasChild(IWmTaskService.NOCHILD);
		if(oConvertUtils.isEmpty(wmTask.getPid())){
			wmTask.setPid(IWmTaskService.ROOT_PID_VALUE);
            wmTask.setAncestors(IWmPlanService.ANCESTORS);
		}else{
			//如果当前节点父ID不为空 则设置父节点的hasChildren 为1
			WmTask parent = baseMapper.selectById(wmTask.getPid());
			if(parent!=null && !"1".equals(parent.getHasChild())){
				parent.setHasChild("1");
				baseMapper.updateById(parent);
			}

            if(parent != null) {
                wmTask.setAncestors(parent.getAncestors() + "," + parent.getId());
            }
		}
		baseMapper.insert(wmTask);

        //新增任务BOM
        if (wmTask.getItemOrProduct().equals(UserConstant.PRODUCT_ITEM)){
            WmTaskBom wmTaskBom = new WmTaskBom();
            wmTaskBom.setNeedNum(wmTask.getQuantity());
            wmTaskBom.setWmPlanId(wmTask.getPlanId());
            wmTaskBom.setProcessUserId(wmTask.getProcessUserId());
            wmTaskBom.setWmTaskId(wmTask.getId());
            taskBomMapper.insert(wmTaskBom);
        }
	}
	
	@Override
    @Transactional
	public void updateWmTask(WmTask wmTask) {
		WmTask entity = this.getById(wmTask.getId());
		if(entity==null) {
			throw new JeecgBootException("未找到对应实体");
		}
		String old_pid = entity.getPid();
		String new_pid = wmTask.getPid();
		if(!old_pid.equals(new_pid)) {
			updateOldParentNode(old_pid);
			if(oConvertUtils.isEmpty(new_pid)){
				wmTask.setPid(IWmTaskService.ROOT_PID_VALUE);
			}
			if(!IWmTaskService.ROOT_PID_VALUE.equals(wmTask.getPid())) {
				baseMapper.updateTreeNodeStatus(wmTask.getPid(), IWmTaskService.HASCHILD);
			}
		}
		baseMapper.updateById(wmTask);

        //删除该计划已有的BOM
        taskBomMapper.deletePlanBomByTask(wmTask.getPlanId(), wmTask.getId());

        //新增任务BOM
        if (wmTask.getItemOrProduct().equals(UserConstant.PRODUCT_ITEM)){
            WmTaskBom wmTaskBom = new WmTaskBom();
            wmTaskBom.setNeedNum(wmTask.getQuantity());
            wmTaskBom.setWmPlanId(wmTask.getPlanId());
            wmTaskBom.setProcessUserId(wmTask.getProcessUserId());
            wmTaskBom.setWmTaskId(wmTask.getId());
            taskBomMapper.insert(wmTaskBom);
        }
	}
	
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteWmTask(String id) throws JeecgBootException {
		//查询选中节点下所有子节点一并删除
        id = this.queryTreeChildIds(id);
        if(id.indexOf(",")>0) {
            StringBuffer sb = new StringBuffer();
            String[] idArr = id.split(",");
            for (String idVal : idArr) {
                if(idVal != null){
                    WmTask wmTask = this.getById(idVal);
                    String pidVal = wmTask.getPid();
                    //查询此节点上一级是否还有其他子节点
                    List<WmTask> dataList = baseMapper.selectList(new QueryWrapper<WmTask>().eq("pid", pidVal).notIn("id",Arrays.asList(idArr)));
                    boolean flag = (dataList == null || dataList.size() == 0) && !Arrays.asList(idArr).contains(pidVal) && !sb.toString().contains(pidVal);
                    if(flag){
                        //如果当前节点原本有子节点 现在木有了，更新状态
                        sb.append(pidVal).append(",");
                    }

                    //删除该计划已有的BOM
                    taskBomMapper.deletePlanBom(wmTask.getPlanId());
                }
            }
            //批量删除节点
            baseMapper.deleteBatchIds(Arrays.asList(idArr));
            //修改已无子节点的标识
            String[] pidArr = sb.toString().split(",");
            for(String pid : pidArr){
                this.updateOldParentNode(pid);
            }
        }else{
            WmTask wmTask = this.getById(id);
            if(wmTask==null) {
                throw new JeecgBootException("未找到对应实体");
            }
            updateOldParentNode(wmTask.getPid());
            baseMapper.deleteById(id);
        }
	}
	
	@Override
    public List<WmTask> queryTreeListNoPage(QueryWrapper<WmTask> queryWrapper) {
        List<WmTask> dataList = baseMapper.selectList(queryWrapper);
        List<WmTask> mapList = new ArrayList<>();
        for(WmTask data : dataList){
            String pidVal = data.getPid();
            //递归查询子节点的根节点
            if(pidVal != null && !IWmTaskService.NOCHILD.equals(pidVal)){
                WmTask rootVal = this.getTreeRoot(pidVal);
                if(rootVal != null && !mapList.contains(rootVal)){
                    mapList.add(rootVal);
                }
            }else{
                if(!mapList.contains(data)){
                    mapList.add(data);
                }
            }
        }
        return mapList;
    }

    @Override
    public List<SelectTreeModel> queryListByCode(String parentCode) {
        String pid = ROOT_PID_VALUE;
        if (oConvertUtils.isNotEmpty(parentCode)) {
            LambdaQueryWrapper<WmTask> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(WmTask::getPid, parentCode);
            List<WmTask> list = baseMapper.selectList(queryWrapper);
            if (list == null || list.size() == 0) {
                throw new JeecgBootException("该编码【" + parentCode + "】不存在，请核实!");
            }
            if (list.size() > 1) {
                throw new JeecgBootException("该编码【" + parentCode + "】存在多个，请核实!");
            }
            pid = list.get(0).getId();
        }
        return baseMapper.queryListByPid(pid, null);
    }

    @Override
    public List<SelectTreeModel> queryListByPid(String pid) {
        if (oConvertUtils.isEmpty(pid)) {
            pid = ROOT_PID_VALUE;
        }
        return baseMapper.queryListByPid(pid, null);
    }

	/**
	 * 根据所传pid查询旧的父级节点的子节点并修改相应状态值
	 * @param pid
	 */
	private void updateOldParentNode(String pid) {
		if(!IWmTaskService.ROOT_PID_VALUE.equals(pid)) {
			Long count = baseMapper.selectCount(new QueryWrapper<WmTask>().eq("pid", pid));
			if(count==null || count<=1) {
				baseMapper.updateTreeNodeStatus(pid, IWmTaskService.NOCHILD);
			}
		}
	}

	/**
     * 递归查询节点的根节点
     * @param pidVal
     * @return
     */
    private WmTask getTreeRoot(String pidVal){
        WmTask data =  baseMapper.selectById(pidVal);
        if(data != null && !IWmTaskService.ROOT_PID_VALUE.equals(data.getPid())){
            return this.getTreeRoot(data.getPid());
        }else{
            return data;
        }
    }

    /**
     * 根据id查询所有子节点id
     * @param ids
     * @return
     */
    private String queryTreeChildIds(String ids) {
        //获取id数组
        String[] idArr = ids.split(",");
        StringBuffer sb = new StringBuffer();
        for (String pidVal : idArr) {
            if(pidVal != null){
                if(!sb.toString().contains(pidVal)){
                    if(sb.toString().length() > 0){
                        sb.append(",");
                    }
                    sb.append(pidVal);
                    this.getTreeChildIds(pidVal,sb);
                }
            }
        }
        return sb.toString();
    }

    /**
     * 递归查询所有子节点
     * @param pidVal
     * @param sb
     * @return
     */
    private StringBuffer getTreeChildIds(String pidVal,StringBuffer sb){
        List<WmTask> dataList = baseMapper.selectList(new QueryWrapper<WmTask>().eq("pid", pidVal));
        if(dataList != null && dataList.size()>0){
            for(WmTask tree : dataList) {
                if(!sb.toString().contains(tree.getId())){
                    sb.append(",").append(tree.getId());
                }
                this.getTreeChildIds(tree.getId(),sb);
            }
        }
        return sb;
    }

    @Override
    @Transactional
    public ProductBomResDto uploadProcessBom(List<ProductBomReqDto> list, String wmPlanId){
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        WmPlan wmPlanExist = planMapper.selectById(wmPlanId);
        if(wmPlanExist == null){
            throw new RuntimeException("计划不存在");
        }
        else{
            wmPlanExist.setProcessUserId(sysUser.getId());
            planMapper.updateById(wmPlanExist);
        }

        List<ProductBomReqDto> newList = new ArrayList<>();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        String batchNo = format.format(new Date());
        try {
            //删除该计划已有的BOM
            taskBomMapper.deletePlanBom(wmPlanId);

            //循环处理上传的产品
            for (ProductBomReqDto bomNode : list) {
                if (StringUtils.isEmpty(bomNode.getName())) {
                    bomNode.setStatus("物料名称缺失");
                    bomNode.setResult("fail");
                    newList.add(bomNode);
                    continue;
                }

                //新增任务信息
                WmTask wmTask = new WmTask();
                wmTask.setPlanId(wmPlanExist.getId());
                wmTask.setName(bomNode.getName());
                wmTask.setProcessUserId(sysUser.getId());
                if(!StringUtils.isEmpty(bomNode.getPcode())) {
                    WmTask wmTaskParent = findByCodeAndPlan(bomNode.getPcode(), wmPlanExist.getId());
                    if (wmTaskParent != null) {
                        wmTask.setPid(wmTaskParent.getId());
                    }
                }
                addWmTask(wmTask);

                //新增任务BOM
                if (bomNode.getItemOrProduct().equals(UserConstant.PRODUCT_ITEM)){
                    WmTaskBom wmTaskBom = new WmTaskBom();
                    wmTaskBom.setNeedNum(bomNode.getQuantity());
                    wmTaskBom.setWmPlanId(wmPlanId);
                    wmTaskBom.setProcessUserId(sysUser.getId());
                    wmTaskBom.setWmTaskId(wmTask.getId());
                    wmTaskBom.setName(bomNode.getName());
                    wmTaskBom.setCode(bomNode.getCode());
                    wmTaskBom.setUnitOfMeasure(bomNode.getUnitOfMeasure());
                    wmTaskBom.setSpecification(bomNode.getSpecification());
                    wmTaskBom.setMaterial(bomNode.getMaterial());
                    wmTaskBom.setSize(bomNode.getSize());
                    wmTaskBom.setGbNumber(bomNode.getGbNumber());
                    wmTaskBom.setMingCheng(bomNode.getMingCheng());
                    wmTaskBom.setGotowhere(bomNode.getGotowhere());
                    wmTaskBom.setCaiLiao(bomNode.getCaiLiao());
                    wmTaskBom.setGuiGe(bomNode.getGuiGe());
                    wmTaskBom.setProcessNo(bomNode.getProcessNo());
                    wmTaskBom.setOtherRequire(bomNode.getOtherRequire());
                    wmTaskBom.setSeriesNo(bomNode.getSeriesNo());
                    wmTaskBom.setRemark(bomNode.getRemark());
                    taskBomMapper.insert(wmTaskBom);
                }

                bomNode.setStatus("导入成功");
                bomNode.setResult("success");
                newList.add(bomNode);
            }
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }

        ProductBomResDto wmBomResultVo = new ProductBomResDto();
        wmBomResultVo.setBomNodeList(newList);
        wmBomResultVo.setBatchNo(batchNo);
        return wmBomResultVo;
    };

    //通过编码和计划ID查询计划
    private WmTask findByCodeAndPlan(String code, String contractProductId){
        LambdaQueryWrapper<WmTask> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WmTask::getCode, code).eq(WmTask::getPlanId, contractProductId).last("LIMIT 1");
        WmTask wmTaskParent = getOne(queryWrapper);
        return wmTaskParent;
    };

    @Override
    public void deleteWmTaskBom(List<String> taskIdList){
        for(String id: taskIdList){
            WmTask wmTask = baseMapper.selectById(id);
            taskBomMapper.deletePlanBomByTask(wmTask.getPlanId(), id);
        }
    };

    @Override
    public void confirmProcess(String wmPlanId, String type, String userId, String processStatus){
        baseMapper.confirmProcess(wmPlanId, type, userId, processStatus);
    };

    @Override
    @Transactional
    public void transferTask(List<String> idList, String userId, String memo){
        for(String taskId: idList){
            WmTask wmTask = baseMapper.selectById(taskId);
            if(wmTask != null){
                wmTask.setChargeUserId(userId);
                baseMapper.updateById(wmTask);
            }
        }
    };

    @Override
    public void setWantedUser(List<String> idList, String userId){
        for(String id: idList){
            WmTask wmTask = baseMapper.selectById(id);
            wmTask.setWantedStatus(UserConstant.WANTED_STATUS_PREPARE);
            wmTask.setWantedUserId(userId);
            baseMapper.updateById(wmTask);
        }
    };

    @Override
    public void setStorageUser(List<String> idList, String userId){
        for(String id: idList){
            WmTask wmTask = baseMapper.selectById(id);
            wmTask.setStorageStatus(UserConstant.STORAGE_STATUS_PREPARE);
            wmTask.setStorageUserId(userId);
            baseMapper.updateById(wmTask);
        }
    };

    @Override
    @Transactional
    public void finishStorage(List<String> idList){
        for(String id: idList){
            //获取和更新任务
            WmTask wmTask = baseMapper.selectById(id);
            wmTask.setChargeUserId(wmTask.getWantedUserId());//负责人设置为报料人员
            wmTask.setStorageStatus(UserConstant.STORAGE_STATUS_FINISHED);
            baseMapper.updateById(wmTask);

            //获取计划采购的BOM列表
            List<WmTaskBom> wmTaskBomList = taskBomMapper.getPlanApplyBom(wmTask.getPlanId());
            for(WmTaskBom wmTaskBom: wmTaskBomList){
                if(wmTaskBom.getNeedNum() > 0 && wmTaskBom.getPurchaseNum() > 0){
                    //生成采购订单
                    WmPurchaseOrder wmPurchaseOrder = new WmPurchaseOrder();
                    wmPurchaseOrder.setCode(wmTaskBom.getCode());
                    wmPurchaseOrder.setName(wmTaskBom.getName());
                    wmPurchaseOrder.setSpecification(wmTaskBom.getSpecification());
                    wmPurchaseOrder.setUnitOfMeasure(wmTaskBom.getUnitOfMeasure());
                    wmPurchaseOrder.setMaterial(wmTaskBom.getMaterial());
                    wmPurchaseOrder.setSize(wmTaskBom.getSize());
                    wmPurchaseOrder.setGotowhere(wmTaskBom.getGotowhere());
                    wmPurchaseOrder.setOtherRequire(wmTaskBom.getOtherRequire());
                    wmPurchaseOrder.setPurchaseNum(wmTaskBom.getPurchaseNum());
                    wmPurchaseOrder.setProcessNo(wmTaskBom.getProcessNo());
                    wmPurchaseOrder.setSeriesNo(wmTaskBom.getSeriesNo());
                    wmPurchaseOrder.setWmTaskId(id);
                    wmPurchaseOrder.setRemark(wmTaskBom.getRemark());
                    purchaseOrderMapper.insert(wmPurchaseOrder);
                }
            }
        }
    };
}
